﻿// ## 2023/12/15 # 黑店小小二 # 修复都市金钱过大导致的数据溢出 ##
// ## 2023/11/07 # 铃 # 删除AI买卖兵装部分(挪到单独cpp中),大幅增加买卖兵装的量,但是价格更差.减少玩家重复的无效操作. ##
// ## 2023/09/07 # 黑店小小二 # 执行武将仍可再次行动bug ##
// ## 2023/08/27 # 江东新风 # 兵装选择闪退bug和兵器名显示异常修复 ##
// ## 2023/06/21 # 江东新风 # 兵装和攻具的买卖整合到一个对话框 ##
// ## 2022/08/14 # 铃 # 仅有格式更改。 ##
// ## 2022/02/14 # 江东新风 # 部分常量中文化 ##
// ## 2022/02/02 # 江东新风 # 购买价格上调 ##
// ## 2021/04/18 # 白马叔叔 # AI兵装购买、优化算法、调整关下城购买兵装 ##
// ## 2021/01/31 # 江东新风 # rand函数错误修复 ##
// ## 2021/01/12 # 江东新风 # 加入特色都市设定，价格微调 ##
// ## 2021/01/07 # 江东新风 # 兵装买卖重做,商才价格优待#
// ## 2020/12/12 # 江东新风 # 修复trace参数报错 ##
// ## 2020/09/21 # 江东新风 # ch::add_tp替换 ##
// ## 2020/08/10 #messi#全篇校对語句##
// ## 2020/08/09 # 氕氘氚 # 添加港?的兵器买卖，把菜单放到【买卖】下，修复金大於65535时计算出錯的bug##
// ## 2020/08/08 # 氕氘氚 # 把菜单放到【城市】下##
/*
@제작자: HoneyBee
@설명: 창,극,노,군마를 매매 (태수의 정치력이 관여)

*/

namespace WEAPON_TRADE
{

    // ================ CUSTOMIZE ================

    const int TP_COST = 30;
    const int ACTION_COST = 20;

    const int KEY = pk::hash("兵装买卖");

    const float 买兵装倍率上限 = 2.0f;
    const float 买兵装倍率下限 = 1.2f;

    const float 卖兵装倍率上限 = 1.2f;
    const float 卖兵装倍率下限 = 0.6f;

    // ===========================================

    const array<array<int>> dlg92_data = {
        {0, -1, 320, 1, 0, 0, 284, 64, 0},
        {2, 4391, 70, 9, 12, 54, 445, 318, 0},
        {9, 4391, 430, 1, 284, 36, 144, 32, 0},
        {0, 4391, 321, 1, 428, 36, 40, 28, 0},
        {9, 4391, 432, 1, 5, 64, 16, 302, 0},
        {9, 4391, 431, 1, 456, 64, 16, 302, 0},
        {0, 4391, 323, 1, 5, 366, 252, 60, 0},
        {9, 4391, 433, 1, 257, 366, 147, 64, 0},
        {0, 4391, 322, 1, 404, 366, 64, 48, 0},
        {2, -1, 499, 9, 21, 70, 428, 264, 0},
        {0, 4400, 313, 1, 422, 259, 8, 8, 0},
        {0, 4400, 314, 1, 422, -2, 8, 8, 0},
        {0, 4400, 315, 1, -3, 259, 8, 8, 0},
        {0, 4400, 316, 1, -3, -2, 8, 8, 0},
        {9, 4400, 428, 1, 5, -2, 417, 8, 0},
        {9, 4400, 428, 1, 5, 259, 417, 8, 0},
        {9, 4400, 435, 1, 422, 6, 8, 253, 0},
        {9, 4400, 435, 1, -3, 6, 8, 253, 0},
        {9, -1, 524, 1, 72, 73, 326, 167, 0},
        {9, 4409, 525, 1, -48, 0, 48, 167, 0},
        {9, 4409, 526, 1, 326, 0, 48, 167, 0},
        {6, -1, -1, -1, 60, 22, 48, 24, 24},
        {2, -1, 327, 9, 118, 252, 174, 18, 0},
        {8, -1, 190, 24, 29, 248, 78, 26, 0},
        {7, -1, -1, 0, 120, 254, 170, 14, 0},
        {2, -1, 393, 9, 118, 278, 42, 22, 0},
        {6, 4416, -1, -1, 13, 3, 16, 16, 80},
        {2, -1, 327, 9, 162, 278, 130, 22, 0},
        {6, 4418, -1, -1, 4, 3, 120, 16, 400},
        {2, -1, 393, 9, 118, 304, 42, 22, 0},
        {6, 4420, -1, -1, 5, 3, 32, 16, 80},
        {2, -1, 327, 9, 162, 304, 130, 22, 0},
        {6, 4422, -1, -1, 4, 3, 120, 16, 400},
        {5, -1, 172, 8, 27, 376, 88, 44, 0},
        {5, -1, 180, 8, 115, 376, 96, 44, 0},
        {2, -1, 327, 9, 89, 342, 58, 22, 0},
        {6, -1, -1, -1, 94, 345, 48, 16, 400},
        {7, -1, -1, 0, 115, 78, 326, 128, 0},
        {8, -1, 190, 24, 29, 78, 78, 26, 0},
        {2, -1, 393, 9, 118, 210, 74, 22, 0},
        {6, 4430, -1, -1, 5, 3, 64, 16, 80},
        {2, -1, 327, 9, 194, 210, 220, 22, 0},
        {6, 4432, -1, -1, 5, 3, 210, 16, 400},
        {2, -1, 393, 9, 29, 342, 58, 22, 0},
        {6, -1, -1, -1, 34, 345, 48, 16, 400},
        {8, -1, 190, 24, 29, 210, 78, 26, 0}};

    const array<array<int>> dlg181_data = {
        {9, -1, 426, 1, 0, 0, 326, 128, 0},
        {2, -1, 366, 9, 5, 8, 70, 86, 0},
        {7, -1, -1, 0, 8, 11, 64, 80, 0},
        {2, -1, 393, 9, 242, 5, 42, 22, 0},
        {6, 9209, -1, -1, 5, 3, 32, 16, 80},
        {2, -1, 411, 9, 286, 5, 34, 22, 0},
        {6, 9211, -1, -1, 5, 3, 24, 16, 400},
        {2, -1, 393, 9, 242, 29, 42, 22, 0},
        {6, 9213, -1, -1, 5, 3, 32, 16, 80},
        {2, -1, 411, 9, 286, 29, 34, 22, 0},
        {6, 9215, -1, -1, 5, 3, 24, 16, 400},
        {2, -1, 393, 9, 242, 53, 42, 22, 0},
        {6, 9217, -1, -1, 5, 3, 32, 16, 80},
        {2, -1, 411, 9, 286, 53, 34, 22, 0},
        {6, 9219, -1, -1, 5, 3, 24, 16, 400},
        {2, -1, 393, 9, 242, 77, 42, 22, 0},
        {6, 9221, -1, -1, 5, 3, 32, 16, 80},
        {2, -1, 411, 9, 286, 77, 34, 22, 0},
        {6, 9223, -1, -1, 5, 3, 24, 16, 400},
        {2, -1, 393, 9, 242, 101, 42, 22, 0},
        {6, 9225, -1, -1, 5, 3, 32, 16, 80},
        {2, -1, 411, 9, 286, 101, 34, 22, 0},
        {6, 9227, -1, -1, 5, 3, 24, 16, 400},
        {2, -1, 411, 9, 3, 98, 74, 22, 0},
        {6, 9229, -1, -1, 5, 3, 64, 16, 80},
        {2, -1, 608, 9, 0, 0, 326, 128, 0},
        {9, -1, 429, 1, 74, 2, 8, 124, 0},
        {9, -1, 429, 1, 233, 2, 8, 124, 0},
        {6, -1, -1, -1, 182, 105, 32, 16, 80},
        {6, -1, -1, -1, 102, 105, 32, 16, 80},
        {6, -1, -1, -1, 83, 46, 32, 16, 80},
        {6, -1, -1, -1, 141, 7, 32, 16, 80},
        {6, -1, -1, -1, 201, 46, 32, 16, 80},
        {0, -1, 1406, 1, 113, 22, 90, 90, 0}

    };

    const int 组件_兵器名按键 = 1;
    const int 组件_金数量展示 = 3;
    const int 组件_兵器名2 = 4;
    const int 组件_兵器数量展示 = 5;
    const int 组件_决定 = 6;
    const int 组件_返回 = 7;
    const int 组件_行动力展示 = 8;
    const int 组件_执行武将 = 9;
    const int 组件_交易效果 = 10;
    const int 组件_交易效果展示 = 11;
    const int 组件_行动力 = 12;
    const int 组件_兵装选择 = 13;
    const int 组件_末 = 14;

    const array<string> dlg92_desc = {
        "兵装商人",
        "枪",
        "金",
        "0",
        "枪",
        "0",
        "决定",
        "返回",
        "0/0",
        "执行武将",
        "交易效果",
        "0",
        "行动力",
        "兵装选择"};

    class Main
    {
        pk::building @building_ = @null;
        // dlg181相关
        pk::dialog @dlg92_ = @null;
        pk::dialog @dlg181_ = @null;
        pk::dialog @dlg320_ = @null;
        array<pk::text @> text92_(组件_末, null);
        array<pk::button @> button92_(组件_末, null);
        pk::slider @slider92_ = @null;
        array<pk::text @> text181_(16, null);
        pk::chart @chart181_ = @null;
        pk::face @face181_ = @null;
        pk::building @building92_ = @null;
        pk::person @actor92_ = @null;
        int choose_weapon_id_ = 1; // 默认为1，枪
        int after_gold_ = -1;
        int after_weapon_num_ = -1;

        Main()
        {
            pk::bind(102, pk::trigger102_t(onGameInit));
            add_menu();
        }

        void add_menu()
        {
            pk::menu_item 兵装买卖;
            兵装买卖.menu = 100;
            兵装买卖.shortcut = "6";
            兵装买卖.init = pk::building_menu_item_init_t(init);
            兵装买卖.is_visible = pk::menu_item_is_visible_t(isVisible);
            兵装买卖.is_enabled = pk::menu_item_is_enabled_t(isEnabled);
            兵装买卖.get_text = pk::menu_item_get_text_t(getText);
            兵装买卖.get_desc = pk::menu_item_get_desc_t(getDesc);
            兵装买卖.handler = pk::menu_item_handler_t(handler);
            pk::add_menu_item(兵装买卖);

            pk::menu_item 据点兵装买卖;
            据点兵装买卖.menu = 据点内政::据点_parent;
            据点兵装买卖.shortcut = "6";
            据点兵装买卖.init = pk::building_menu_item_init_t(init);
            据点兵装买卖.is_visible = pk::menu_item_is_visible_t(isVisible);
            据点兵装买卖.is_enabled = pk::menu_item_is_enabled_t(isEnabled);
            据点兵装买卖.get_text = pk::menu_item_get_text_t(getText);
            据点兵装买卖.get_desc = pk::menu_item_get_desc_t(getDesc);
            据点兵装买卖.handler = pk::menu_item_handler_t(handler);
            pk::add_menu_item(据点兵装买卖);
            // 据点_parent
        }
        ////////////////////////////////////////////////////////////////菜单相关/////////////////////////////////////////////////////////////////////////

        void init(pk::building @building)
        {
            @building_ = @building;
        }

        string getText()
        {
            return pk::encode("兵装商人");
        }

        bool isVisible()
        {
            if (pk::is_campaign())
                return false;
            if (!ch::get_set_p(0).get_mod_set(买卖菜单扩展_开关))
                return false;
            if (building_.get_id() >= 据点_末)
                return false;
            return true;
        }

        bool isEnabled()
        {
            auto person_list = pk::get_idle_person_list(building_);
            int result = check_avaliable(building_, person_list);
            if (result != 0)
                return false;
            else
                return true;
        }

        string getDesc()
        {
            auto person_list = pk::get_idle_person_list(building_);
            int result = check_avaliable(building_, person_list);
            switch (result)
            {
            case 1:
                return pk::encode("本回合已执行过买卖");
            case 2:
                return pk::encode(pk::format("技巧值不足 (必须 {} 技巧值)", TP_COST));
            case 3:
                return pk::encode(pk::format("行动力不足 (必须 {} 行动力)", ACTION_COST));
            case 4:
                return pk::encode("无可执行武将");
            case 0:
                return pk::encode(pk::format("执行兵装买卖.(消耗技巧点{},行动力{})", TP_COST, ACTION_COST));
            default:
                return pk::encode("");
            }
            return pk::encode("");
        }

        int check_avaliable(pk::building @building, pk::list<pk::person @> list) // 之所以加入list是为了ai调用时不用重复计算，玩家菜单稍微多点操作问题不大
        {
            // pk::trace(pk::format("3.1:{}{}{}{}", pk::enemies_around(building), list.count, pk::get_district(building.get_district_id()).ap < ACTION_GAIN, pk::get_gold(building) < GOLD_COST));
            pk::person @taishu0 = pk::get_person(pk::get_taishu_id(building));
            auto district = pk::get_district(building.get_district_id());
            if (ch::get_base_p(building.get_id()).weapon_merchant_done)
                return 1;
            else if (pk::get_force(building.get_force_id()).tp < TP_COST)
                return 2;
            else if (district is null or district.ap < ACTION_COST)
                return 3;
            else if (list.count == 0)
                return 4;
            else
                return 0;
        }

        bool handler()
        {
            @dlg92_ = init_dlg92();
            pk::dialog @n_dialog = @dlg92_;
            if (n_dialog is null)
                return false;
            open_dlg92(n_dialog, building_);

            return true;
        }
        /////////////////////////////////////////////////////////////初始化相关//////////////////////////////////////////////////////////////////////////////
        void onGameInit()
        {
            // 游戏开始时初始化菜单，以后只要显示隐藏
            //@ dlg92_ = init_dlg92();
        }

        /////////////////////////////////////////////////////////////对话框相关//////////////////////////////////////////////////////////////////////////////

        void select_person(pk::dialog @dialog, pk::building @building)
        {
            pk::list<pk::person @> person_list = pk::get_idle_person_list(building);

            // 禁止无可用武将时打开，就不需在此判断了
            // if (person_list.count == 0)
            //     return false;

            pk::list<pk::person @> person_sel;
            person_list.sort(function(a, b) {
                return (a.stat[武将能力_政治] > b.stat[武将能力_政治]); // 무장 정렬 (지력순)
            });
            pk::list<pk::person @> person_default;
            person_default.add(person_list[0]);
            dialog.set_visible(false);
            person_sel = pk::person_selector(pk::encode("武将选择"), pk::encode("选择可执行的武将."), person_list, 1, 1, person_default, 9);
            dialog.set_visible(true);
            if (person_sel.count > 0)
            {
                update_dlg181(dlg181_, @person_sel[0]);
                update_dlg92(dlg92_, building, @person_sel[0], choose_weapon_id_);
            }
        }

        bool set_weapon_num(pk::building @building, pk::person @actor, int weapon_id)
        {
            int weapon_num = pk::get_weapon_amount(building, weapon_id);
            pk::int_int num = get_trade_weapon_num(building, actor, weapon_id);
            pk::int_bool numpad = pk::numberpad(pk::encode("兵装买卖"), weapon_num - num.second, weapon_num + num.first, weapon_num, pk::numberpad_t(pad_callback));

            if (!numpad.second)
                return false;
            slider92_.set_value(numpad.first);
            return true;
        }

        string pad_callback(int line, int original_value, int current_value)
        {
            return pk::encode("输入交易数量"); // 텍스트 표시기능인 듯 하나, 사용방법 모르겠음
        }

        int choose_weapon(pk::dialog @dialog, pk::building @building, pk::person @actor)
        {
            // 从tex_id 630开始是剑
            // add_titlebar可以添加让对话框拖动的抬头
            @dlg92_ = @dialog;
            @building92_ = @building;
            @actor92_ = @actor;

            pk::dialog @child_dialog;
            if (dialog !is null)
                @child_dialog = dialog.create_dialog(false); //@child_dialog = pk::new_dialog();//
            else
                @child_dialog = pk::new_dialog(false);
            @dlg320_ = @child_dialog;
            child_dialog.set_visible(false);
            pk::button @ok_button = dlg_320(child_dialog, pk::size(440, 320), pk::encode("兵器选择")); // 62*4

            set_dlg320(child_dialog, building);

            child_dialog.set_visible(true); //

            pk::detail::funcref func0 = cast<pk::button_on_released_t @>(function(button) {
                main.button92_[组件_兵器名按键].set_text(ch::get_weapon_name(main.choose_weapon_id_));
                main.text92_[组件_兵器名2].set_text(ch::get_weapon_name(main.choose_weapon_id_));
                main.update_dlg92(main.dlg92_, main.building92_, main.actor92_, main.choose_weapon_id_);
                main.dlg320_.set_visible(false);
            });
            ok_button.on_button_released(func0);
            return 0;
        }

        void open_dlg92(pk::dialog @dialog, pk::building @building)
        {
            @building92_ = @building;

            // 初始选择武将设置
            pk::list<pk::person @> person_list = pk::get_idle_person_list(building);
            person_list.sort(function(a, b) {
                return (a.stat[武将能力_政治] > b.stat[武将能力_政治]); // 무장 정렬 (지력순)
            });

            @actor92_ = @person_list[0];

            update_dlg92(dialog, building, actor92_, choose_weapon_id_); // 这里需改成实际值
            update_dlg181(dlg181_, actor92_);

            // dialog.set_visible(true);
            dialog.open();
            dialog.delete();
        }

        pk::dialog @init_dlg92()
        {
            // 对话框初始化
            pk::dialog @new_dialog = pk::new_dialog();
            @dlg92_ = @new_dialog;
            pk::size dialog_size = pk::size(470, 450);
            new_dialog.set_pos(pk::get_resolution().width / 2 - dialog_size.width / 2, pk::get_resolution().height / 2 - dialog_size.height / 2);
            new_dialog.set_size(dialog_size);
            new_dialog.set_visible(false);
            init_dlg_from_arr(new_dialog, dlg92_data, 4391);
            set_dlg92();
            @dlg181_ = @init_dlg181(new_dialog);

            pk::detail::funcref func0 = cast<pk::widget_on_destroy_t @>(function(widget) { main.reset_class_value(); });
            new_dialog.on_widget_destroy(func0);

            return new_dialog;
        }

        // 181是武将中信息框，基于92，所以就应该是92生成的
        pk::dialog @init_dlg181(pk::dialog @parent)
        {
            pk::dialog @new_dialog;
            if (parent !is null)
            {
                @new_dialog = parent.create_dialog(false);
            }
            else
            {
                @new_dialog = pk::new_dialog();
            }

            init_dlg_from_arr(new_dialog, dlg181_data, 9206);
            pk::size dialog_size = pk::size(326, 128);
            //
            if (parent !is null)
                new_dialog.set_pos(115, 78);
            else
                new_dialog.set_pos(pk::get_resolution().width / 2 - dialog_size.width / 2, pk::get_resolution().height / 2 - dialog_size.height / 2);
            new_dialog.set_size(dialog_size);
            // new_dialog.set_visible(false);

            // 不需要额外摧毁dlg181,已验证父dialog destroy时，会提前摧毁所包含的所有组件，包括生成的dialog
            // pk::detail::funcref func0 = cast<pk::widget_on_destroy_t@>(function(widget) { pk::trace("dlg181_ destroy"); });
            // new_dialog.on_widget_destroy(func0);

            return new_dialog;
        }

        // 作为对话框背景模板，可随意调节大小
        pk::button @dlg_320(pk::dialog @dialog, pk::size size, string &title)
        {
            pk::assert(size.width >= 301);
            pk::assert(size.height >= 16);

            pk::widget @w = dialog.create_sprite(70); //(70);//70是半透明
            w.set_pos(12, 54);
            w.set_size(size);
            @w = dialog.create_sprite(499); //(70);//70是半透明
            w.set_pos(12, 54);
            w.set_size(size);

            @w = dialog.create_image(320);
            // dialog.add_titlebar(w.get_id(), 320);

            pk::text @t = dialog.create_text();
            t.set_pos(40, 22);
            t.set_size(pk::get_text_size(FONT_BIG, title));
            t.set_text(title);
            t.set_text_font(FONT_BIG);

            @w = dialog.create_sprite(430);
            // dialog.add_titlebar(w.get_id(), 430);
            w.set_pos(284, 36);
            w.set_size(size.width - 301, w.get_size().height);

            @w = dialog.create_image(321);
            w.set_pos(size.width - 17, 36);
            // dialog.add_titlebar(w.get_id(), 320);

            @w = dialog.create_sprite(432);
            w.set_pos(5, 64);
            w.set_size(w.get_size().width, size.height - 16);

            @w = dialog.create_sprite(431);
            w.set_pos(size.width + 11, 64);
            w.set_size(w.get_size().width, size.height - 16);

            @w = dialog.create_image(323);
            w.set_pos(5, size.height + 48);

            @w = dialog.create_sprite(433);
            w.set_pos(257, size.height + 48);
            w.set_size(size.width - 298, w.get_size().height);

            @w = dialog.create_image(322);
            w.set_pos(size.width - 41, size.height + 48);

            pk::button @ok_button = dialog.create_button(172);
            ok_button.set_pos(27, size.height + 58);
            ok_button.set_text(pk::encode("决定"));

            dialog.resize();

            return ok_button;
        }

        void set_dlg320(pk::dialog @dialog, pk::building @building)
        {
            bool has_tech0 = pk::has_tech(building, 技巧_开发木兽);
            bool has_tech1 = pk::has_tech(building, 技巧_开发投石);

            array<int> arr(兵器_末 - 1, -1);
            array<pk::button @> btn(兵器_末, null);
            for (int i = 0; i < 兵器_战马; ++i)
            {
                pk::image @im0 = dialog.create_image(631 + i);
                im0.set_size(62, 62);
                im0.set_pos(70 + 90 * (i % 4), 48 + 70 + 100 * (i / 4));

                pk::button @btn0 = dialog.create_button(190);
                btn0.set_size(62, 26);
                btn0.set_pos(70 - 5 + 90 * (i % 4), 48 + 70 + 62 + 100 * (i / 4));
                btn0.set_text(pk::encode("选择"));
                arr[i] = btn0.get_id();
                @btn[i] = @btn0;
            }
            // 冲车设置取消隐藏木兽左移一格，井阑左移一格，投石左移2格，楼船和斗舰的移动
            // 冲车
            int a = 兵器_冲车 - 1;
            pk::image @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * (a % 4), 48 + 70 + 100 * (a / 4));
            im0.set_visible(!has_tech0);

            pk::button @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * (a % 4), 48 + 70 + 62 + 100 * (a / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(!has_tech0);

            // 井阑
            a = 兵器_井阑 - 1;
            @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * (a % 4), 48 + 70 + 100 * (a / 4));
            im0.set_visible(!has_tech1);

            @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * (a % 4), 48 + 70 + 62 + 100 * (a / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(!has_tech1);

            // 投石
            a = 兵器_投石 - 1;
            @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * ((a - 1) % 4), 48 + 70 + 100 * ((a - 1) / 4));
            im0.set_visible(has_tech1);

            @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * ((a - 1) % 4), 48 + 70 + 62 + 100 * ((a - 1) / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(has_tech1);

            // 木兽
            a = 兵器_木兽 - 1;
            @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * ((a - 3) % 4), 48 + 70 + 100 * ((a - 3) / 4));
            im0.set_visible(has_tech0);

            @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * ((a - 3) % 4), 48 + 70 + 62 + 100 * ((a - 3) / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(has_tech0);

            a = 兵器_走舸 - 1;
            @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * ((a - 3) % 4), 48 + 70 + 100 * ((a - 3) / 4));
            im0.set_visible(false);

            @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * ((a - 3) % 4), 48 + 70 + 62 + 100 * ((a - 3) / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(false);

            // 楼船
            a = 兵器_楼船 - 1;
            @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * ((a - 3) % 4), 48 + 70 + 100 * ((a - 3) / 4));
            im0.set_visible(!has_tech1);

            @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * ((a - 3) % 4), 48 + 70 + 62 + 100 * ((a - 3) / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(!has_tech1);

            // 斗舰
            a = 兵器_斗舰 - 1;
            @im0 = dialog.create_image(631 + a);
            im0.set_size(62, 62);
            im0.set_pos(70 + 90 * ((a - 4) % 4), 48 + 70 + 100 * ((a - 4) / 4));
            im0.set_visible(has_tech1);

            @btn0 = dialog.create_button(190);
            btn0.set_size(62, 26);
            btn0.set_pos(70 - 5 + 90 * ((a - 4) % 4), 48 + 70 + 62 + 100 * ((a - 4) / 4));
            btn0.set_text(pk::encode("选择"));
            arr[a] = btn0.get_id();
            @btn[a] = @btn0;
            btn0.set_visible(has_tech1);

            pk::detail::funcref func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 1; });
            btn[0].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 2; });
            btn[1].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 3; });
            btn[2].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 4; });
            btn[3].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 5; });
            btn[4].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 6; });
            btn[5].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 7; });
            btn[6].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 8; });
            btn[7].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 9; });
            btn[8].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 10; });
            btn[9].on_button_pressed(func0);
            func0 = cast<pk::button_on_pressed_t @>(function(button) { main.choose_weapon_id_ = 11; });
            btn[10].on_button_pressed(func0);
            // func0 = cast<pk::button_on_pressed_t@>(function(button) { main.choose_weapon_id_ = 11; });
            // btn[11].on_button_pressed(func0);
            
            // add_button_group 默认选中第一个，这里调整下已选的兵装
            int sel_id = arr[choose_weapon_id_ - 1];
            arr.removeAt(choose_weapon_id_ - 1);
            arr.insertAt(0, sel_id);
            dialog.add_button_group(arr);
            // if (main.choose_weapon_id_ > 0 and main.choose_weapon_id_ < 兵器_斗舰)pk::left_click(btn[main.choose_weapon_id_]);
        }

        void update_dlg181(pk::dialog @dialog, pk::person @person)
        {
            // 0-4统武智政魅描述5-9数值，10武将名 11-15描述
            for (int i = 武将能力_统率; i < 武将能力_末; ++i)
            {
                text181_[i * 2].set_text(pk::encode(ch::get_stat_name(i)));

                text181_[i * 2 + 1].set_text(pk::encode(pk::format("{}", person.stat[i])));

#if param_set
                chart181_.set_value(i, float(float(person.stat[i]) / (pk::get_stat_param().max_stat - 10)));
#endif
#if not_param_set
                chart181_.set_value(i, float(float(person.stat[i]) / (int(pk::core["person.max_stat"]) - 10)));
#endif
               
            }
            text181_[11].set_text(pk::encode(ch::get_stat_name(武将能力_智力)));
            text181_[12].set_text(pk::encode(ch::get_stat_name(武将能力_政治)));
            text181_[13].set_text(pk::encode(ch::get_stat_name(武将能力_魅力)));
            text181_[14].set_text(pk::encode(ch::get_stat_name(武将能力_统率)));
            text181_[15].set_text(pk::encode(ch::get_stat_name(武将能力_武力)));
            text181_[10].set_text(pk::get_name(person));
            face181_.set_face(person.face);
        }

        // 设置一些特殊组件的特殊配置，在构建完基本界面后进行
        void set_dlg92()
        {
            pk::detail::funcref func0 = cast<pk::button_on_released_t @>(function(button) { main.select_person(main.dlg92_, main.building92_); });
            button92_[组件_执行武将].on_button_released(func0);

            pk::detail::funcref func1 = cast<pk::button_on_released_t @>(function(button) { main.choose_weapon(main.dlg92_, main.building92_, main.actor92_); });
            button92_[组件_兵装选择].on_button_released(func1);

            pk::detail::funcref func2 = cast<pk::button_on_released_t @>(function(button) { main.set_weapon_num(main.building92_, main.actor92_, main.choose_weapon_id_); });
            button92_[组件_兵器名按键].on_button_released(func2);

            pk::detail::funcref funcslider = cast<pk::slider_on_value_changed_t @>(function(self, value) {
                main.slider_value_change(main.building92_, main.actor92_, main.choose_weapon_id_, value);
                // main.text92_[5].set_text(pk::encode(pk::format("{}⇒{}", main.slider92_.get_value(), value)));
            });
            slider92_.on_slider_value_changed(funcslider);

            pk::detail::funcref func3 = cast<pk::button_on_released_t @>(function(button) {
                int weapon_id = main.choose_weapon_id_;
                int weapon_change = main.after_weapon_num_ - pk::get_weapon_amount(main.building92_, weapon_id);
                main.conduct_trade_result(main.building92_, weapon_id, weapon_change, main.after_gold_ - pk::get_gold(main.building92_));
                pk::dialog @parent = @main.dlg92_; //@button.get_parent();
                // parent.set_visible(false);
                parent.close(1);
                // parent.close(1);
                // parent.delete();
                if (weapon_change != 0)
                {
                    main.actor92_.action_done = true;
                }

                main.reset_trade_value();
            });
            button92_[组件_决定].on_button_released(func3);

            pk::detail::funcref func4 = cast<pk::button_on_released_t @>(function(button) {
                pk::dialog @parent = @main.dlg92_; //@button.get_parent();
                // parent.set_visible(false);
                parent.close(1);
                // parent.close(1);
                // parent.delete();
                main.reset_trade_value();
            });
            button92_[组件_返回].on_button_released(func4);
        }

        void update_dlg92(pk::dialog @dialog, pk::building @building, pk::person @actor, int weapon_id)
        {
            // pk::detail::funcref funcslider = cast<pk::slider_on_value_changed_t@>(function(self, value) { main.text92_[5].set_text( pk::encode(pk::format("{}⇒{}", main.slider92_.get_value(), value))); });
            // slider.on_slider_value_changed(funcslider);
            @building92_ = @building;
            @actor92_ = @actor;
            auto district = pk::get_district(building.get_district_id());

            int gold = pk::get_gold(building);
            int weapon_num = pk::get_weapon_amount(building, weapon_id);
            text92_[组件_行动力展示].set_text(pk::encode(pk::format("{}/{}", ACTION_COST, district.ap)));
            text92_[组件_金数量展示].set_text(pk::encode(pk::format("{}⇒{}", gold, gold)));
            text92_[组件_兵器数量展示].set_text(pk::encode(pk::format("{}⇒{}", weapon_num, weapon_num)));
            int buy_rate = get_weapon_rate(weapon_id, actor, building, true);
            int sale_rate = get_weapon_rate(weapon_id, actor, building, false);
            int buy_cost = ch::get_weapon_cost(weapon_id) * buy_rate / 100;

            int sale_cost = ch::get_weapon_cost(weapon_id) * sale_rate / 100;

            if (weapon_id <= 兵器_战马)
            {
                float buy_price = 1 / (4000 * 10 / buy_cost / 10.0) * 100;
                float sell_price = 1 / (4000 * 10 / sale_cost / 10.0) * 100;
                text92_[组件_交易效果展示].set_text(pk::encode(pk::format("买:{}金/100个|卖:{}金/100个", int(buy_price), int(sell_price))));
            }
            else
            {
                float buy_price =   buy_cost ;
                float sell_price =  sale_cost ;
                text92_[组件_交易效果展示].set_text(pk::encode(pk::format("买:{}金/个 | 卖:{}金/1个", int(buy_price), int(sell_price))));
            }

            pk::int_int num = get_trade_weapon_num(building, actor, weapon_id);
            slider92_.set_min_max(weapon_num - num.second, weapon_num + num.first);
            slider92_.set_value(weapon_num);

            after_gold_ = gold; // 储存初始值，以便在决定时应用
            after_weapon_num_ = weapon_num;
        }

        // 此函数用于设置通用基础属性及储存组件信息
        pk::dialog @init_dlg_from_arr(pk::dialog @new_dialog, array<array<int>> arr, int start_id)
        {

            // int start_id = 5595;
            int id = 0;
            int text_index = 0;
            for (int i = 0; i < int(arr.length); ++i)
            {
                // if (i == (5526 - start_id) or i == (5527 - start_id) or i == (5528 - start_id)) continue;
                pk::widget @widget = ch::create_widget(new_dialog,arr[i][0], arr[i][2]);
                int parent = arr[i][1];

                int x = arr[i][4] + ((parent == -1) ? 0 : arr[parent - start_id][4]);
                int y = arr[i][5] + ((parent == -1) ? 0 : arr[parent - start_id][5]);
                int width = arr[i][6];
                int height = arr[i][7];

                if (widget !is null)
                {
                    widget.set_pos(x, y);
                    widget.set_size(width, height);
                }

                // dlg92(买卖主窗体)的特殊设定
                if (start_id == 4391)
                {
                    // 按键的设置
                    if (arr[i][0] == 5 or arr[i][0] == 8)
                    {
                        pk::button @button = @widget;
                        button.set_text(pk::encode(dlg92_desc[id]));
                        button.set_text_align(TEXT_ALIGN_MIDDLE | TEXT_ALIGN_CENTER);

                        @button92_[id] = @widget;
                        id += 1;
                    }
                    // 文本的设置
                    if (arr[i][0] == 6)
                    {
                        pk::text @text = @widget;
                        text.set_text(pk::encode(dlg92_desc[id]));
                        text.set_text_align(TEXT_ALIGN_MIDDLE | TEXT_ALIGN_CENTER);
                        if (id == 0)
                            text.set_text_font(FONT_BIG);
                        @text92_[id] = @text;
                        id += 1;
                    }

                    if (arr[i][0] == 7 and x == 120)
                    {
                        pk::slider @slider = new_dialog.create_slider();
                        slider.set_pos(x, y);
                        slider.set_size(width, height);
                        slider.set_min_max(0, 100);
                        slider.set_value(50);
                        @slider92_ = @slider;
                    }
                }

                // dlg181(武将信息窗)的特殊设定
                if (start_id == 9206)
                {
                    // pk::trace(pk::format("parent:{},x:{},y:{},arr[i][4]:{},arr[i][5]:{}",parent,x,y, arr[i][4], arr[i][5]));
                    if (i == 2)
                    {
                        pk::face @face = new_dialog.create_face();
                        face.set_pos(x, y);
                        face.set_face_size(pk::size(width, height));
                        face.set_face_type(1, 0);

                        @face181_ = @face;
                    }
                    if (arr[i][2] == 1406)
                    {
                        pk::chart @chart = new_dialog.create_chart();
                        chart.set_pos(x + 45, y + 45);
                        chart.set_scale(0.45);
                        chart.set_value(0, 1);
                        chart.set_value(1, 0.7);
                        chart.set_value(2, 0.8);
                        chart.set_value(3, 0.9);
                        chart.set_value(4, 1);
                        @chart181_ = @chart;
                    }
                    if (arr[i][0] == 6)
                    {

                        @text181_[text_index] = @widget;
                        text181_[text_index].set_text_align(TEXT_ALIGN_MIDDLE | TEXT_ALIGN_CENTER);
                        text_index += 1;
                    }
                }
            }

            return new_dialog;
        }

        void slider_value_change(pk::building @building, pk::person @actor, int weapon_id, int value)
        {
            // value是即将要变为的值
            int weapon_num = pk::get_weapon_amount(building, weapon_id);
            int change_num = value - weapon_num;
            bool is_buy = (change_num > 0);
            int pre_gold = pk::get_gold(building);
            int after_gold = 0;
            int buy_rate = 0;
            int buy_cost = 0;
            if (is_buy)
            {
                buy_rate = get_weapon_rate(weapon_id, actor, building, true);
                buy_cost = ch::get_weapon_cost(weapon_id) * buy_rate / 100;
                after_gold = pre_gold - change_num * buy_cost / (weapon_id > 兵器_战马 ? 1 : 4000);
                // pk::trace(pk::format("buy_rate:{},buy_cost:{},change_num:{},pre_gold :{},after_gold :{}", buy_rate,buy_cost,change_num,pre_gold ,after_gold ));
            }
            else
            {
                int sale_rate = get_weapon_rate(weapon_id, actor, building, false);
                int sale_price = ch::get_weapon_cost(weapon_id) * sale_rate / 100;
                after_gold = pre_gold - change_num * sale_price / (weapon_id > 兵器_战马 ? 1 : 4000);
            }

            text92_[组件_金数量展示].set_text(pk::encode(pk::format("{}⇒{}", pre_gold, after_gold)));
            text92_[组件_兵器数量展示].set_text(pk::encode(pk::format("{}⇒{}", weapon_num, value)));
            after_gold_ = after_gold; // 储存变化的值，以便在决定时应用
            after_weapon_num_ = value;
            return;
        }

        pk::int_int get_trade_weapon_num(pk::building @building, pk::person @actor, int weapon_id)
        {
            int buy_rate = get_weapon_rate(weapon_id, actor, building, true);
            int sale_rate = get_weapon_rate(weapon_id, actor, building, false);
            int buy_cost = ch::get_weapon_cost(weapon_id) * buy_rate / 100;
            int sale_price = ch::get_weapon_cost(weapon_id) * sale_rate / 100;

            int weapon_num = pk::get_weapon_amount(building, weapon_id);
            // 最大可买数量
            int stat_buy_num = weapon_id > 兵器_战马 ? (actor.stat[武将能力_政治] / 30 + 1) : (actor.stat[武将能力_政治] * 100 + 10000);
            int gold_buy_num = weapon_id > 兵器_战马 ? (pk::get_gold(building) / buy_cost) : (pk::get_gold(building) / buy_cost * 4000);
            int store_buy_num = pk::get_max_weapon_amount(building, weapon_id) - weapon_num;
            int buy_num = pk::min(stat_buy_num, gold_buy_num, store_buy_num);

            // 最大可卖数量
            int stat_sale_num = stat_buy_num;
            int store_sale_num = weapon_num;
            int max_gold_gain = pk::get_max_gold(building) - pk::get_gold(building);
            int gold_sale_num = weapon_id > 兵器_战马 ? (max_gold_gain / sale_price) : (max_gold_gain / sale_price * 4000);
            int sale_num = pk::min(stat_sale_num, store_sale_num, gold_sale_num);
            pk::trace(pk::decode(pk::get_name(actor)) + "," + buy_num + "," + sale_num);
            return pk::int_int(buy_num, sale_num);
        }

        bool conduct_trade_result(pk::building @building, int weapon_id, int weapon_change, int gold_change)
        {
            // pk::add_gold(main.building92_, main.after_gold_ - pk::get_gold(main.building92_), true);'
            if (weapon_change != 0)
            {
                pk::add_gold(building, gold_change, true);
                pk::add_weapon_amount(building, weapon_id, weapon_change, true);

                ch::add_tp(pk::get_force(building.get_force_id()), -TP_COST, building.pos);

                auto district = pk::get_district(building.get_district_id());
                pk::add_ap(district, -ACTION_COST);
            }
            return true;
        }

        void reset_class_value()
        {
            @dlg92_ = @null;
            @dlg181_ = @null;
            @dlg320_ = @null;
            for (int i = 0; i < 组件_末; ++i)
            {
                @text92_[i] = @null;
                @button92_[i] = @null;
            }
            for (int i = 0; i < 16; ++i)
            {
                @text181_[i] = @null;
            }

            @slider92_ = @null;
            @chart181_ = @null;
            @face181_ = @null;
        }

        void reset_trade_value()
        {
            @building92_ = @null;
            @actor92_ = @null;
            choose_weapon_id_ = 1; // 默认为1，枪
            after_gold_ = -1;
            after_weapon_num_ = -1;
        }

    } Main main;

    // 便于外部调用
    pk::dialog @init_dialog92()
    {
        return main.init_dlg92();
    }

    int get_weapon_rate(int weapon_id, pk::person @actor, pk::building @base, bool buy = true)
    {
        // 系数计算，调整只需处理price_max和price_min, 按价格差来最后浮动过于变态，还是按数量差
        float cost_rate_max = buy ? 买兵装倍率上限 : 卖兵装倍率上限;
        float cost_rate_min = buy ? 买兵装倍率下限 : 卖兵装倍率下限;
        // float price_min = 0.0875f;
        float per_stat_buf = (cost_rate_max - cost_rate_min) * 0.35f * 1.f / 70.f;
        float per_store_buf = (cost_rate_max - cost_rate_min) * 0.35f;
        float per_skill_buf = (cost_rate_max - cost_rate_min) * 0.15f;
        float per_rate_buf = (cost_rate_max - cost_rate_min) * 0.15f * 1.f / 40.f;
        float per_specialty_buf = (cost_rate_max - cost_rate_min) * 0.2f;

        float specialty_buf = 0.0f;
        if (base.facility == 0)
        {
            int weapon_heishu = pk::equipment_id_to_heishu(weapon_id);

            if (pk::building_to_city(base).tokusan[weapon_heishu])
                specialty_buf = per_specialty_buf;
        }
        else if (base.facility == 1 or base.facility == 2)
        {

            int weapon_heishu = pk::equipment_id_to_heishu(weapon_id);
            if (pk::get_city(pk::get_city_id(base.pos)).tokusan[weapon_heishu])
                specialty_buf = 0.5f * per_specialty_buf;
        }
        float stat_buf = per_stat_buf * (pk::max(0, actor.stat[武将能力_政治] - 50));
        float store_buf = weapon_id > 兵器_战马 ? (per_store_buf * pk::max(0, pk::min(15, 15 - pk::get_weapon_amount(base, weapon_id))) / 15.f) : (per_store_buf * pk::get_weapon_amount(base, weapon_id) / pk::get_max_weapon_amount(base, weapon_id)); // 卖是10
        float skill_buf = (ch::has_skill(actor, 特技_商才) ? per_skill_buf : 0.0f);
        float rate_buf = (pk::get_city(pk::get_city_id(base.pos)).rate - 30) * per_rate_buf;

        // 每件攻具的价格倍率
        float multi = 1.0f;
        if (buy)
        {
            multi = pk::max(cost_rate_min, cost_rate_max - (stat_buf + store_buf + skill_buf + rate_buf) - specialty_buf) * (weapon_id > 兵器_战马 ? 1.5f : 1.1f) * 100.f;
        }
        else
        {
            multi = pk::min(cost_rate_max, cost_rate_min + (stat_buf + store_buf + skill_buf + rate_buf) - specialty_buf) * 100.f;
        }
        // int PER_GOLD_COST = int(get_weapon_cost(weapon_id) * 1.5f * multi);
        return int(multi);
    }

}